/*
 *    Copyright (c) 2006 ThoughtWorks, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.thoughtworks.turtlemock.internal;

import com.thoughtworks.turtlemock.constraint.Constraint;
import com.thoughtworks.turtlemock.fluapi.Should;
import junit.framework.Assert;

public abstract class BaseInvokeMethodResultLog extends AbstractRollbackableInvokeLog implements InvokeMethodResultLog {
    private String operationName;
    private Thread invokingThread;

    protected BaseInvokeMethodResultLog(String operationName) {
        this.operationName = operationName;
        this.invokingThread = Thread.currentThread();
    }

    public InvokeWithArgsResultLog with(Object param) {
        return withArgs(new Object[]{param});
    }

    public InvokeWithArgsResultLog with(Object param1, Object param2) {
        return withArgs(new Object[]{param1, param2});
    }

    public InvokeWithArgsResultLog with(Object param1, Object param2, Object param3) {
        return withArgs(new Object[]{param1, param2, param3});
    }

    public InvokeWithArgsResultLog with(Object param1, Object param2, Object param3, Object param4) {
        return withArgs(new Object[]{param1, param2, param3, param4});
    }

    public InvokeWithArgsResultLog withArgs(Object[] args) {
        Constraint[] constrains = new Constraint[args.length];
        for (int i = 0; i < args.length; i++) {
            constrains[i] = Should.eq(args[i]);
        }
        return withArgsConstraint(constrains);
    }

    public String getOperationName() {
        return operationName;
    }

    public InvokeMethodResultLog inAnotherThread() {
        Assert.assertNotSame("should invoke mock object in other thread but not", invokingThread, Thread.currentThread());
        return this;
    }

    public InvokeWithArgsResultLog withFirstArgConstraint(Constraint constraint) {
        return withArgConstraint(constraint, 0);
    }

    public InvokeMethodResultLog then(String operationName) {
        throw new UnsupportedOperationException("method: then(String operationName); arg: operationName=" + operationName);
    }

}
